import { DynamicInstanceConfig, IPSAppView, PSModelServiceProxyImpl, PSModelServiceImpl, IPSControl, IPSModelObject, IPSEditor } from "@ibiz/dynamic-model-api";
import { Http } from "ibz-core";

/**
 * @description 模型服务实现类
 * @class ModelService
 * @extends {PSModelServiceImpl}
 */
 class ModelService extends PSModelServiceImpl {

  public model: IModel;

  /**
   * Creates an instance of ModelService.
   * @memberof ModelService
   */
  constructor() {
    super();
    this.getModelJson = async (strPath: string, config: DynamicInstanceConfig): Promise<IModel> => {
      let url: string = `/json${strPath}`;
      try {
          const result: any = await Http.getInstance().get(url);
          return result.data ? result.data : null;
      } catch (error) {
          return null;
      }
    }
  }

  /**
   * @description 获取模型对象
   * @param {string} cls
   * @param {string} strPath
   * @param {IModel} [model]
   * @return {*}  {Promise<IPSModelObject>}
   * @memberof ModelServiceImpl
   */
  async getPSModel(cls: string, strPath: string, model?: IModel): Promise<IPSModelObject> {
    const _model = model ? model : await this.loadModel(strPath);
    this.model = _model;
    if (_model) {
      // 创建模型对象
      const psModelObj = this.createPSModelObject(null, cls, _model);
      if (psModelObj != null) {
        const iPSModelService = this.getPSModelService(cls, psModelObj);
        psModelObj.init(iPSModelService, null, strPath, _model);
        this.store.setModelCache(cls, strPath, psModelObj);
      } else {
        console.warn(`模型对象[${cls}]创建失败!`);
      }
      return psModelObj;
    }
    if (this.pInstance) {
      return this.pInstance.getPSModel(cls, strPath);
    }
  }

}


export class ModelServiceUtil {
  /**
   * @description 唯一实例对象
   * @static
   * @memberof ModelServiceUtil
   */
  public static instance = new ModelServiceUtil();

  /**
   * @description 模型服务代理对象
   * @private
   * @type {PSModelServiceProxyImpl}
   * @memberof ModelServiceUtil
   */
  private modelServiceProxy: PSModelServiceProxyImpl = new PSModelServiceProxyImpl();

  /**
   * @description 模型服务
   * @private
   * @type {ModelServiceImpl}
   * @memberof ModelServiceUtil
   */
  private service!: ModelService;

  /**
   * @description 获取模型服务实例对象
   * @static
   * @return {*}  {ModelService}
   * @memberof ModelServiceUtil
   */
  public static getInstance(): ModelServiceUtil {
    if (!ModelServiceUtil.instance) {
      ModelServiceUtil.instance = new ModelServiceUtil();
    }
    return ModelServiceUtil.instance;
  }

  /**
   * Creates an instance of ModelService.
   * @memberof ModelServiceUtil
   */
  constructor() {
    this.init();
  }

  /**
   * @description 初始化模型服务
   * @private
   * @memberof ModelServiceUtil
   */
  private init() {
    const model = new ModelService();
    this.modelServiceProxy.init(model, '');
    this.service = this.modelServiceProxy.getRealPSModelService() as ModelService;
  }

  /**
   * @description 获取视图模型
   * @param {string} path 路径
   * @return {*}  {Promise<IPSAppView>}
   * @memberof ModelServiceUtil
   */
  public async getViewModel(path: string): Promise<IPSAppView> {
    return await this.modelServiceProxy.getPSAppView(path);
  }

  /**
   * @description 获取部件模型
   * @param {string} path
   * @return {*}  {Promise<IPSControl>}
   * @memberof ModelServiceUtil
   */
  public async getControlModel(path: string): Promise<IPSControl> {
    if (this.service) {
      return await this.service.getPSModel('control.IPSControl', path) as IPSControl;
    }
  }

  /**
   * @description 获取编辑器模型
   * @param {string} path
   * @return {*}  {Promise<IPSEditor>}
   * @memberof ModelServiceUtil
   */
  public async getEditorModel(path: string): Promise<IPSEditor> {
    if (this.service) {
      return await this.service.getPSModel('control.IPSEditor', path) as IPSEditor;
    }
  }

  /**
   * @description 获取模型实例对象
   * @param {string} path 模型路径
   * @param {string} [type='VIEW'] 模型类型
   * @return {*} 
   * @memberof ModelServiceUtil
   */
  public async getModelInstance(path: string, type: string = 'VIEW'): Promise<{ model: IModel, instance: IPSAppView | IPSControl | IPSEditor | undefined }> {
    if (path == '' || path == null || path == undefined) {
      return undefined;
    }
    let instance: IPSAppView | IPSControl | IPSEditor | undefined = undefined;
    switch (type) {
      case 'VIEW':
        instance = await this.getViewModel(path);
        break;
      case 'CONTROL':
        instance = await this.getControlModel(path);
        break;
      case 'EDITOR':
        instance = await this.getEditorModel(path);
        break;
    }
    return {
      model: this.service.model,
      instance: instance
    }
  }

  /**
   * @description 刷新模型
   * @param {IModel} model
   * @param {string} [type='VIEW']
   * @return {*}  {(Promise<{ model: IModel, instance: IPSAppView | IPSControl | IPSEditor | undefined }>)}
   * @memberof ModelServiceUtil
   */
  public async refreshModel(model: IModel, type: string = 'VIEW'): Promise<{ model: IModel, instance: IPSAppView | IPSControl | IPSEditor | undefined }> {
    return new Promise((resolve: any) => {
      if (this.service) {
        let s: string = '';
        switch (type) {
          case 'VIEW':
            s = 'app.view.IPSAppView';
            break;
          case 'CONTROL':
            s = 'control.IPSControl';
            break;
          case 'EDITOR':
            s = 'control.IPSEditor';
            break;
        }
        this.service.getPSModel(s, '', model).then((instance: any) => {
          resolve({
            model: model,
            instance: instance
          })
        })
      }
    })
  }

}